package objects;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;

public class WebManager {
	
	private boolean _CONNECTED = false;
	
	private HttpClient _CLIENT;
	private HttpContext _LOCALCONTEXT;
	private HttpResponse _CACHEDRESPONSE;
	private ResponseHandler<String> _RESPHAND;
	private List<NameValuePair> _LOGINARGS;
	private CookieStore _CSTORE;
	
	// Store URL's
	private String _LOGINURL;

	public WebManager(String Username, String Password,
					  String LOGINURL) {
		
		_CLIENT = new DefaultHttpClient();
		_LOGINARGS = new ArrayList<NameValuePair>();
		_LOCALCONTEXT = new BasicHttpContext();
		_RESPHAND = new BasicResponseHandler();
		
		_LOCALCONTEXT.setAttribute(ClientContext.COOKIE_STORE, _CSTORE);
		_LOGINURL = LOGINURL;
		
		_LOGINARGS.add(new BasicNameValuePair("username", Username));
		_LOGINARGS.add(new BasicNameValuePair("password", Password));
		_LOGINARGS.add(new BasicNameValuePair("keeplogged", "1"));
		
	}
	
	/**
	 * Method used to login to a page, such as a forum login so that the client can
	 * read / send to individual pages.
	 */
	public void doLogin(){
		if(_CONNECTED){
			return;
		}
		
		HttpPost LOGINPAGE = new HttpPost(_LOGINURL);
		try {
			LOGINPAGE.setEntity(new UrlEncodedFormEntity(_LOGINARGS, HTTP.UTF_8));
			_CACHEDRESPONSE = _CLIENT.execute(LOGINPAGE,_LOCALCONTEXT);
			_CACHEDRESPONSE.getEntity().consumeContent();
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (ClientProtocolException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		String CURRENTPAGECONTENTS = null;
		
		try {
			CURRENTPAGECONTENTS = _CLIENT.execute(new HttpGet(_LOGINURL),
								  _RESPHAND, _LOCALCONTEXT);
		} catch (ClientProtocolException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
	
		if(CURRENTPAGECONTENTS.contains("loginform")){
			_CONNECTED = false;
			System.out.println("Login Failed!");
		}else{
			System.out.println("Login Successful!");
			System.out.println(CURRENTPAGECONTENTS);
			_CONNECTED = true;
		}
		_CONNECTED = true;
	}
	
	/**
	 * @param Cookies : Cookies so that the object can be initialized from a preset
	 * set of cookies, such as something that has been serialized/deserialized from a file
	 */
	public WebManager(CookieStore Cookies) {
		
		_CLIENT = new DefaultHttpClient();
		_LOGINARGS = new ArrayList<NameValuePair>();
		_LOCALCONTEXT = new BasicHttpContext();
		_RESPHAND = new BasicResponseHandler();
		
		_LOCALCONTEXT.setAttribute(ClientContext.COOKIE_STORE, _CSTORE);
		
		_CSTORE = Cookies;
		_CONNECTED = true;
	}
	
	
	public CookieStore getCookies(){
		return _CSTORE;
	}
	
	/**
	 * Method for retrieving a page after having logged in.
	 * 
	 * 
	 * @param Page : Obviously the string for the page you want to retrieve.
	 * @return : A String filled with the page's contents.
	 */
	public synchronized String getPage(String Page) {
		if(!_CONNECTED){return null;}
		else{
			String CURRENTPAGECONTENTS = null;
			try {
				CURRENTPAGECONTENTS = _CLIENT.execute(new HttpGet(Page),
								      _RESPHAND, _LOCALCONTEXT);
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}		
			return CURRENTPAGECONTENTS;
		}
	}
	
	/**
	 * @param FileURL : Direct path to file download link
	 * @param FileDirTarget : Local file path to save the torrent to.
	 * @return
	 */
	public synchronized boolean getFileRaw(String FileURL, String FileDirTarget){
		if(!_CONNECTED){return false;}
		
		File fOut;
		FileOutputStream fStreamOut;
		HttpResponse RESP;
		InputStream fSource;
		
		try {
			fOut = new File(FileDirTarget);
			fOut.createNewFile();
			if(!fOut.canWrite()){
				// TODO : No write permissions.
				return false;
			}

			fStreamOut = new FileOutputStream(fOut);
			
			RESP = _CLIENT.execute(new HttpGet(FileURL), _LOCALCONTEXT);
			fSource = RESP.getEntity().getContent();
			
			int cOUT;
			while((cOUT = fSource.read()) != -1){
				fStreamOut.write(cOUT);
			}
			fStreamOut.close();
			fSource.close();
			RESP.getEntity().consumeContent();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	
	public void EnableDebug(){
		_CONNECTED = true;
	}
	
	// Sets.
	
	public void set_LOGINURL(String loginurl) {
		_LOGINURL = loginurl;
	}

}
